/**
 * OWASP GoatDroid Project
 * 
 * This file is part of the Open Web Application Security Project (OWASP)
 * GoatDroid project. For details, please see
 * https://www.owasp.org/index.php/Projects/OWASP_GoatDroid_Project
 *
 * Copyright (c) 2011 - The OWASP Foundation
 * 
 * GoatDroid is published by OWASP under the GPLv3 license. You should read and accept the
 * LICENSE before you use, modify, and/or redistribute this software.
 * 
 * @author Jack Mannino, nVisium Security (https://www.nvisiumsecurity.com)
 * @created 2011
 */
package org.owasp.goatdroid.fourgoats.webservice.login;

import java.sql.SQLException;
import java.util.ArrayList;
import org.owasp.goatdroid.fourgoats.webservice.Constants;
import org.owasp.goatdroid.fourgoats.webservice.Salts;
import org.owasp.goatdroid.fourgoats.webservice.login.LoginDAO;
import org.owasp.goatdroid.fourgoats.webservice.validators.Validators;

public class LoginImpl {

	static public boolean isSessionValid(String sessionToken) {

		try {
			if (!Validators.validateSessionTokenFormat(sessionToken))
				return false;
			LoginDAO dao = new LoginDAO();
			long sessionStart = dao.getSessionStartTime(sessionToken);
			if (LoginUtils.getTimeMilliseconds() - sessionStart < Constants.MILLISECONDS_MONTH) {
				dao.closeConnection();
				return true;
			} else {
				dao.closeConnection();
				return false;
			}
		} catch (InstantiationException e) {
			return false;
		} catch (IllegalAccessException e) {
			return false;
		} catch (ClassNotFoundException e) {
			return false;
		} catch (SQLException e) {
			return false;
		}
	}

	static public LoginBean validateCredentials(String userName, String password) {

		LoginBean bean = new LoginBean();
		ArrayList<String> errors = new ArrayList<String>();

		try {
			LoginDAO dao = new LoginDAO();
			if (Validators.validateCredentials(userName, password)) {
				if (dao.validateCredentials(userName, password)) {
					String userNameAndTime = userName
							+ LoginUtils.getCurrentDateTime();
					long sessionStartTime = LoginUtils.getTimeMilliseconds();
					String sessionToken = LoginUtils.generateSaltedSHA512Hash(
							userNameAndTime, Salts.SESSION_TOKEN_SALT);
					dao.updateSessionInformation(userName, sessionToken,
							sessionStartTime);
					bean.setPreferences(dao.getPreferences(userName));
					bean.setUserName(userName);
					dao.closeConnection();
					bean.setSessionToken(sessionToken);
					bean.setSuccess(true);
					return bean;
				} else {
					dao.closeConnection();
					errors.add(Constants.LOGIN_CREDENTIALS_INVALID);
				}
			} else {
				dao.closeConnection();
				errors.add(Constants.LOGIN_CREDENTIALS_INVALID);
			}
		} catch (InstantiationException e) {
			errors.add(Constants.UNEXPECTED_ERROR);
		} catch (IllegalAccessException e) {
			errors.add(Constants.UNEXPECTED_ERROR);
		} catch (ClassNotFoundException e) {
			errors.add(Constants.UNEXPECTED_ERROR);
		} catch (SQLException e) {
			errors.add(Constants.UNEXPECTED_ERROR);
		}
		bean.setSuccess(false);
		bean.setErrors(errors);
		return bean;
	}

	static public LoginBean checkSession(String sessionToken) {

		LoginBean bean = new LoginBean();
		if (isSessionValid(sessionToken))
			bean.setSuccess(true);
		else
			bean.setSuccess(false);

		return bean;
	}

	static public LoginBean signOut(String sessionToken) {

		LoginBean bean = new LoginBean();
		ArrayList<String> errors = new ArrayList<String>();

		try {
			LoginDAO dao = new LoginDAO();
			if (isSessionValid(sessionToken)
					&& Validators.validateSessionTokenFormat(sessionToken)) {
				dao.terminateSession(sessionToken);
				dao.closeConnection();
				bean.setSuccess(true);
				return bean;
			} else
				errors.add(Constants.NOT_AUTHORIZED);

		} catch (InstantiationException e) {
			errors.add(Constants.UNEXPECTED_ERROR);
		} catch (IllegalAccessException e) {
			errors.add(Constants.UNEXPECTED_ERROR);
		} catch (ClassNotFoundException e) {
			errors.add(Constants.UNEXPECTED_ERROR);
		} catch (SQLException e) {
			errors.add(Constants.UNEXPECTED_ERROR);
		}
		bean.setSuccess(false);
		bean.setErrors(errors);
		return bean;

	}
}
